home *** CD-ROM | disk | FTP | other *** search
Wrap
/*------------------------------------------------------------------------------ SP1_SERV.SQL THIS SCRIPT TAKES THE SERVER-SIDE SYSTEM-PROCS FROM 8.0 to SP1. Changes in this file are organized as follows (please maintain): System Tables (UPGRADE.SQL) System Messages (MESSAGES.SQL / MSGWORK.SQL / SERVMSGS.SQL) Engine System Procs (U_TABLES.SQL / PROCSYST.SQL / ODSOLE.SQL) Schema Procs (OLEDBSCH.SQL / ANSIVIEW.SQL) ODBC/OLEDB Catalog Procs (INSTCAT.SQL) SEM SQLDMO System Procs (SQLDMO.SQL) Changes to these scripts should NOT be placed in this file: Starfighter Procs (XPSTAR.SQL / INSTMSDB.SQL / SQLTRACE.SQL / WEB.SQL) Doc's Samples (INSTPUBS.SQL / INSTNWND.SQL) Replication Procs (REPLSYS.SQL / REPLCOM.SQL / REPLTRAN.SQL / REPLMERG.SQL) These components will maintain separate upgrade scripts. Notes: + Catalog-updates and sp_MS_upd_sysobj_category are enabled for the entire file. Do not disable or re-enable them. Please do not change set options. ------------------------------------------------------------------------------*/ -------------------------------------------------------------------------------- -- VERIFY Server is started in single-user-mode (catalog-updates enables), and -- start marking of system-objects. -------------------------------------------------------------------------------- execute sp_configure 'allow updates',1 go reconfigure with override go exec sp_MS_upd_sysobj_category 1 go -------------------------------------------------------------------------------- -- System Tables (UPGRADE.SQL) -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- System Messages (MESSAGES.SQL / MSGWORK.SQL / SERVMSGS.SQL) English -------------------------------------------------------------------------------- DELETE sysmessages where error in (15355, 21074, 21396 ,8668, 8669 ,13089, 13090, 13091 ,7619 ,1959, 15248 ,21513 ,21512 ,21515, 21516, 21517, 21518, 21519, 21520 ,14359 ,8526 ) go -- 21396 has no corresponding new message. It has been replaced with an updated 21074 insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (15355 ,10 ,0 ,'''sys'' will be a reserved user or role name in next version of SQL Server.', 1033) insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21074,16,0, 'The subscription(s) have been marked inactive and must be reinitialized. NoSync subscriptions will need to be dropped and recreated.', 1033) go insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (8668,16 ,0 ,'An index cannot be created on the view ''%.*ls'' because the select list of the view contains a non-aggregate expression.' ,1033) insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (8669,16 ,0 ,'The indexed view ''%.*ls'' is not updatable.' ,1033) insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (13089 ,10 ,0 ,'lock' ,1033) insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (13090 ,10 ,0 ,'thread' ,1033) insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (13091 ,10 ,0 ,'communication buffer' ,1033) go insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (7619, 16, 0, 'Execution of a full-text operation failed. %ls', 1033) go insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (1959, 16 ,0 ,'Cannot create an index on a view or computed column because the compatibility level of this database is less than 80.' ,1033) insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (15248 ,11 ,0 ,'Either the parameter @objname is ambiguous or the claimed @objtype (%s) is wrong.' ,1033) go insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21513,18,0,'Foreign key column ''%s'' cannot be excluded from a vertical partition.', 1033) go insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21512,18,0,'%ls: The %ls parameter is shorter than the minimum required size.', 1033) GO insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21515,18,0,'Replication custom procedures will not be scripted because the specified publication ''%s'' is a snapshot publication.', 1033) insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21516,10,0,'Transactional replication custom procedures for publication ''%s'' from database ''%s'':', 1033) insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21517,10,0,'Replication custom procedures will not be scripted for article ''%s'' because the auto-generate custom procedures schema option is not enabled.', 1033) insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21518,0,0,'Replication custom procedures for article ''%s'':', 1033) insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21519,10,0,'Custom procedures will not be scripted for article update commands based on direct INSERT, UPDATE, or DELETE statements.', 1033) insert into master..sysmessages (error, severity, dlevel, description, msglangid) values (21520,10,0,'Custom procedure will not be scripted because ''%s'' is not a recognized article update command syntax.', 1033) insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (14359, 16, 0, 'Active Directory is either not enabled on the network or not supported by the operating system.', 1033) go insert into master..sysmessages (error ,severity ,dlevel ,description ,msglangid) values (8526, 16, 0, 'Cannot go remote while the session is enlisted in a distributed transaction that has an active savepoint.', 1033) go -------------------------------------------------------------------------------- -- System Messages (MESSAGES.SQL / MSGWORK.SQL / SERVMSGS.SQL) Localized -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Engine System Procs (U_TABLES.SQL / PROCSYST.SQL / ODSOLE.SQL) -------------------------------------------------------------------------------- update spt_values set low = -2147483648 where number = 1535 and type = 'C' update spt_values set low = -2147483648 where number = 1549 and type = 'C' if object_id('sp_helptext','P') IS NOT NULL drop procedure sp_helptext if object_id('sp_droplogin','P') IS NOT NULL drop procedure sp_droplogin if object_id('sp_addsrvrolemember','P') IS NOT NULL drop procedure sp_addsrvrolemember if object_id('sp_dropsrvrolemember','P') IS NOT NULL drop procedure sp_dropsrvrolemember if object_id('sp_grantdbaccess','P') IS NOT NULL drop procedure sp_grantdbaccess if object_id('sp_addalias','P') IS NOT NULL drop procedure sp_addalias if object_id('sp_addrole','P') IS NOT NULL drop procedure sp_addrole if object_id('sp_addapprole','P') IS NOT NULL drop procedure sp_addapprole if object_id('sp_change_users_login','P') IS NOT NULL drop procedure sp_change_users_login if object_id('sp_fulltext_table','P') IS NOT NULL drop procedure sp_fulltext_table if object_id('sp_fulltext_column','P') IS NOT NULL drop procedure sp_fulltext_column go create procedure sp_droplogin @loginame sysname as declare @exec_stmt nvarchar(890) -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @sid varbinary(85) /*Create temp tables before any DML to ensure dynamic*/ -- CREATE TEMPORARY TABLES FOR LATER USE -- create table #db_list (dbname sysname collate database_default not null, user_name sysname collate database_default not null) create table #retval (job_count int not null) -- CHECK PERMISSIONS -- IF (not is_srvrolemember('securityadmin') = 1) begin dbcc auditevent (104, 2, 0, @loginame, NULL, NULL, NULL) raiserror(15247,-1,-1) return (1) end ELSE begin dbcc auditevent (104, 2, 1, @loginame, NULL, NULL, NULL) end -- DISALLOW USER TRANSACTION -- set implicit_transactions off IF (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_droplogin') return (1) end -- VALIDATE LOGIN NAME (SQL LOGIN) -- select @sid = sid from master.dbo.syslogins where loginname = @loginame and isntname = 0 if (@sid is null) begin raiserror(15007,10,-1,@loginame) return(1) end -- CANNOT CHANGE SA ROLES -- else if @sid = 0x1 -- 'sa' begin raiserror(15405, -1 ,-1, @loginame) return (1) end -- CHECK IF @sid IS CURRENTLY LOGGED IN (ignore cached remote connections) -- if exists(select * from master.dbo.sysprocesses where sid = @sid and status != 'dormant') begin raiserror(15434, -1, -1, @loginame) return(1) end -- CHECK IF ANY DATABASES ARE OWNED BY LOGIN -- if exists(select * from master.dbo.sysdatabases where sid = @sid) begin raiserror(15174, -1, -1, @loginame) select 'Databases owned by login:' = name from master.dbo.sysdatabases where sid = @sid return(1) end -- COLLECT ALL INSTANCES OF USE OF THIS LOGIN IN SYSUSERS -- declare @dbname sysname declare ms_crs_dbname cursor local keyset for select name from master.dbo.sysdatabases open ms_crs_dbname fetch ms_crs_dbname into @dbname while @@fetch_status >= 0 begin if (has_dbaccess(@dbname) = 1) begin select @exec_stmt = 'use ' + quotename( @dbname , '[') + ' insert into #db_list (dbname, user_name) select N'+ quotename( @dbname , '''')+', name from sysusers where sid = suser_sid(N' + quotename( @loginame , '''') + ') ' exec (@exec_stmt) end else raiserror(15622,-1,-1, @dbname) fetch ms_crs_dbname into @dbname end deallocate ms_crs_dbname -- ERROR IF LOGIN USED AS USER IN ANY DATABASE -- if (select count(*) from #db_list) <> 0 begin raiserror(15175,-1,-1,@loginame) select 'Database name:' = dbname, 'User name:' = user_name, 'Mapping type:' = 'user' from #db_list order by dbname return (1) end -- VERIFY NO JOBS IN MSDB OWNED BY THIS LOGIN -- if db_id('msdb') is not null and object_id('msdb.dbo.sp_check_for_owned_jobs') is not null begin exec msdb.dbo.sp_check_for_owned_jobs @loginame, '#retval' if exists (select job_count from #retval where job_count > 0) begin declare @job_count int select @job_count = job_count from #retval raiserror(14248, -1, -1, @job_count) return (1) end end -- DELETE THIS LOGIN (ALSO DELETES REMOTE LOGINS MAPPED TO IT) -- delete from master.dbo.sysxlogins where sid = @sid -- FINALIZATION: SUCCESS/FAILURE MESSAGE if @@rowcount > 0 begin -- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE SYSLOGINS CHANGE -- exec('use master grant all to null') raiserror(15479,-1,-1) return (0) end else begin raiserror(15007,10,-1,@loginame) return (1) end -- sp_droplogin go create procedure sp_addsrvrolemember @loginame sysname, -- login name @rolename sysname = NULL -- server role name as -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @ret int, -- return value of sp call @rolebit smallint, @ismem int, @sid varbinary(85) -- DISALLOW USER TRANSACTION -- set implicit_transactions off IF (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_addsrvrolemember') return (1) end -- VALIDATE SERVER ROLE NAME, CHECKING PERMISSIONS -- select @ismem = is_srvrolemember(@rolename) if @ismem is null begin dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename, NULL) raiserror(15402, -1, -1, @rolename) return (1) end if @ismem = 0 begin dbcc auditevent (108, 1, 0, @loginame, NULL, @rolename, NULL) raiserror(15247,-1,-1) return (1) end -- AUDIT A SUCCESSFUL SECURITY CHECK -- dbcc auditevent (108, 1, 1, @loginame, NULL, @rolename, NULL) -- OBTAIN THE BIT FOR THIS ROLE -- select @rolebit = CASE @rolename WHEN 'sysadmin' THEN 16 WHEN 'securityadmin' THEN 32 WHEN 'serveradmin' THEN 64 WHEN 'setupadmin' THEN 128 WHEN 'processadmin' THEN 256 WHEN 'diskadmin' THEN 512 WHEN 'dbcreator' THEN 1024 WHEN 'bulkadmin' THEN 4096 ELSE NULL END select @sid = sid from master.dbo.syslogins where loginname = @loginame -- ADD ROW FOR NT LOGIN IF NEEDED -- if @sid is null begin execute @ret = sp_MSaddlogin_implicit_ntlogin @loginame if (@ret <> 0) begin raiserror(15007,-1,-1,@loginame) return (1) end end -- CANNOT CHANGE SA ROLES -- else if @sid = 0x1 -- 'sa' begin raiserror(15405, -1 ,-1, @loginame) return (1) end -- UPDATE ROLE MEMBERSHIP -- update master.dbo.sysxlogins set xstatus = xstatus | @rolebit, xdate2 = getdate() where name = @loginame and srvid IS NULL -- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE SYSLOGINS CHANGE -- exec('use master grant all to null') raiserror(15488,-1,-1,@loginame,@rolename) -- FINALIZATION: RETURN SUCCESS/FAILURE return (@@error) -- sp_addsrvrolemember go create procedure sp_dropsrvrolemember @loginame sysname, -- login name @rolename sysname = NULL -- server role name as -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @ret int, -- return value of sp call @rolebit smallint, @ismem int, @sid varbinary(85) -- DISALLOW USER TRANSACTION -- set implicit_transactions off IF (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_dropsrvrolemember') return (1) end -- VALIDATE SERVER ROLE NAME, CHECKING PERMISSIONS -- select @ismem = is_srvrolemember(@rolename) if @ismem is null begin dbcc auditevent (108, 2, 0, @loginame, NULL, @rolename, NULL) raiserror(15402, -1, -1, @rolename) return (1) end if @ismem = 0 begin dbcc auditevent (108, 2, 0, @loginame, NULL, @rolename, NULL) raiserror(15247,-1,-1) return (1) end -- AUDIT THE SUCCESSFUL SECURITY CHECK -- dbcc auditevent (108, 2, 1, @loginame, NULL, @rolename, NULL) -- OBTAIN THE BIT FOR THIS ROLE -- select @rolebit = CASE @rolename WHEN 'sysadmin' THEN 16 WHEN 'securityadmin' THEN 32 WHEN 'serveradmin' THEN 64 WHEN 'setupadmin' THEN 128 WHEN 'processadmin' THEN 256 WHEN 'diskadmin' THEN 512 WHEN 'dbcreator' THEN 1024 WHEN 'bulkadmin' THEN 4096 ELSE NULL END select @sid = sid from master.dbo.syslogins where loginname = @loginame -- ERROR IF USER DOESNT EXIST -- if @sid is null begin raiserror(15007,-1,-1,@loginame) return (1) end -- CANNOT CHANGE SA ROLES -- else if @sid = 0x1 -- 'sa' begin raiserror(15405, -1 ,-1, @loginame) return (1) end -- UPDATE ROLE MEMBERSHIP -- update master.dbo.sysxlogins set xstatus = xstatus & ~@rolebit, xdate2 = getdate() where name = @loginame and srvid IS NULL -- UPDATE PROTECTION TIMESTAMP FOR MASTER DB, TO INDICATE SYSLOGINS CHANGE -- exec('use master grant all to null') raiserror(15489,-1,-1,@loginame,@rolename) -- FINALIZATION: RETURN SUCCESS/FAILURE return (@@error) -- sp_dropsrvrolemember go create procedure sp_grantdbaccess @loginame sysname, @name_in_db sysname = NULL OUT as -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @ret int, -- return value of sp call @uid smallint, @sid varbinary(85), @status smallint if @name_in_db is null select @name_in_db = @loginame -- CHECK PERMISSIONS -- if (not is_member('db_accessadmin') = 1) and (not is_member('db_owner') = 1) begin dbcc auditevent (109, 3, 0, @loginame, @name_in_db, NULL, NULL) raiserror(15247,-1,-1) return (1) end else begin dbcc auditevent (109, 3, 1, @loginame, @name_in_db, NULL, NULL) end -- DISALLOW USER TRANSACTION -- set implicit_transactions off IF (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_grantdbaccess') return (1) end -- VALIDATE NAME-IN-DB -- if @name_in_db <> @loginame begin exec @ret = sp_validname @name_in_db if @ret <> 0 return(1) if (charindex('\', @name_in_db) > 0) begin raiserror(15006,-1,-1,@name_in_db) return (1) end end -- CHECK FOR SPECIAL USER GUEST -- if @name_in_db = 'guest' begin -- ERROR IF NOT USER, OR ALREADY ADDED -- if @loginame <> 'guest' begin raiserror(15062,-1,-1) return(1) end if exists (select * from sysusers where hasdbaccess = 1 and name = 'guest') begin raiserror(15023,-1,-1,'guest') return (1) end -- ENABLE USER GUEST -- update sysusers set status = (status & ~1) | 2, updatedate = getdate() where name = 'guest' return (0) end -- VALIDATE LOGIN NAME (OBTAIN SID) -- select @status = case when (charindex('\', @loginame) <> 0) then 4 else 0 end if @status = 0 select @sid = sid from master.dbo.syslogins -- sql user where isntname = 0 and loginname = @loginame if @sid is null begin -- NT GROUPS REQUIRE DOMAIN NAME -- if @status = 4 select @sid = get_sid('\G'+@loginame, NULL) -- nt group if @sid is null begin select @sid = get_sid('\U'+@loginame, NULL) -- nt user if @sid is not null select @status = 12 end end -- PREVENT USE OF CERTAIN LOGINS -- else if @sid = 0x1 -- 'sa' begin raiserror(15405, -1, -1, @loginame) return (1) end if @sid is null begin if @status = 0 raiserror(15007,-1,-1,@loginame) else raiserror(15401,-1,-1,@loginame) return (1) end -- CHECK IF LOGIN ALREADY IN DATABASE -- if exists (select sid from sysusers where sid = @sid) begin -- ERROR IF LOGIN IS ALREADY ALIASED -- if exists (select sid from sysusers where sid = @sid and isaliased = 1) begin raiserror(15022,-1,-1) return (1) end -- ERROR IF ALREADY EXISTS UNDER DIFFERENT NAME -- if (not user_sid(user_id(@name_in_db)) = @sid) begin raiserror(15063,-1,-1) return (1) end -- ERROR IF LOGIN ALREADY HAS ACCESS -- if exists (select sid from sysusers where sid = @sid and hasdbaccess = 1) begin if @status = 4 raiserror(15024,-1,-1,@name_in_db) else raiserror(15023,-1,-1,@name_in_db) return (1) end -- GIVE DATABASE ACCESS TO THIS LOGIN -- update sysusers set status = (status & ~1) | 2, updatedate = getdate() where sid = @sid return @@error end if @name_in_db = 'sys' raiserror(15355,-1,-1) if user_id(@name_in_db) is not null OR @name_in_db IN ('system_function_schema','INFORMATION_SCHEMA') begin -- SYSUSERS NAME ALREADY EXISTS -- if @status = 4 raiserror(15024,-1,-1,@name_in_db) else raiserror(15023,-1,-1,@name_in_db) return (1) end -- OBTAIN NEW UID (RESERVE 1-4) -- if user_name(5) IS NULL select @uid = 5 else select @uid = min(uid)+1 from sysusers where uid >= 5 and uid < (16384 - 1) -- stay in users range and user_name(uid+1) is null -- uid not in use if @uid is null begin raiserror(15065,-1,-1) return (1) end -- INSERT SYSUSERS ROW -- insert into sysusers select @uid, @status | 2, @name_in_db, @sid, 0x00, getdate(), getdate(), 0, NULL -- INVALIDATE CACHED PERMISSIONS -- grant all to null -- PRINT SUCCESS -- raiserror(15341,-1,-1, @loginame) -- RETURN SUCCESS STATUS -- return @@error -- sp_grantdbaccess go create procedure sp_addalias @loginame sysname, -- name of the pretender @name_in_db sysname -- user to whom to alias the login as -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @sid varbinary(85), @targuid smallint, @newuid smallint, @status smallint, @dbname sysname -- CHECK PERMISSIONS -- if (not is_member('db_accessadmin') = 1) and (not is_member('db_owner') = 1) begin raiserror(15247,-1,-1) return (1) end -- DISALLOW USER TRANSACTION -- set implicit_transactions off IF (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_addalias') return (1) end -- VALIDATE LOGIN NAME (OBTAIN SID) -- select @status = CASE WHEN charindex('\', @loginame) > 0 THEN 12 ELSE 0 END if @status = 0 select @sid = suser_sid(@loginame) -- sql user -- retry sql user as nt with dflt domain if @sid is null begin select @sid = get_sid('\U'+@loginame, NULL) -- nt user if @sid is null begin if @status = 0 raiserror(15007,-1,-1,@loginame) else raiserror(15401,-1,-1,@loginame) return (1) end select @status = 12 end -- PREVENT USE OF CERTAIN LOGINS -- else if @sid = 0x1 begin raiserror(15405, -1, -1, @loginame) return (1) end -- VALIDATE NAME-IN-DB (OBTAIN TARGET UID) -- select @targuid = uid from sysusers where name = @name_in_db and (issqluser = 1 or isntuser = 1) and uid NOT IN (3,4) -- INFORMATION_SCHEMA, system_function_schema if @targuid is null begin raiserror(15008,-1,-1,@name_in_db) return (1) end -- ERROR IF LOGIN ALREADY IN DATABASE -- if exists (select sid from sysusers where sid = @sid) begin -- ERROR IF ALREADY ALIASED -- if exists (select sid from sysusers where sid = @sid and isaliased = 1) begin raiserror(15022,-1,-1) return (1) end -- ERROR: LOGIN ALREADY A USER -- select @name_in_db = name, @dbname = db_name() from sysusers where sid = @sid raiserror(15278,-1,-1,@loginame,@name_in_db,@dbname) return (1) end -- ALTER NAME TO AVOID CONFLICTS IN NAME SPACE -- select @loginame = '\' + @loginame if user_id(@loginame) is not null begin raiserror(15023,-1,-1,@loginame) return (1) end -- OBTAIN NEW UID (RESERVE 1-4) -- if user_name(5) IS NULL select @newuid = 5 else select @newuid = min(uid)+1 from sysusers where uid >= 5 and uid < (16384 - 1) -- stay in users range and user_name(uid+1) is null -- uid not in use if @newuid is null begin raiserror(15065,-1,-1) return (1) end -- INSERT SYSUSERS ROW -- insert into sysusers select @newuid, @status | 16, @loginame, @sid, 0x00, getdate(), getdate(), @targuid, NULL -- FINALIZATION: PRINT/RETURN SUCCESS -- if @@error <> 0 return (1) raiserror(15340,-1,-1) return (0) -- sp_addalias go create procedure sp_addrole @rolename sysname, -- name of new role @ownername sysname = 'dbo' -- name of owner of new role as -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @ret int, -- return value of sp call @uid smallint, @owner smallint -- CHECK PERMISSIONS -- if (not is_member('db_securityadmin') = 1) and (not is_member('db_owner') = 1) begin dbcc auditevent (111, 1, 0, NULL, NULL, @rolename, NULL) raiserror(15247,-1,-1) return (1) end else begin dbcc auditevent (111, 1, 1, NULL, NULL, @rolename, NULL) end -- DISALLOW USER TRANSACTION -- set implicit_transactions off if (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_addrole') return (1) end -- RESOLVE OWNER NAME -- select @owner = uid from sysusers where name = @ownername and isaliased = 0 AND uid NOT IN (0,3,4) --public/INFO_SCHEMA/etc can't own role if @owner is null begin raiserror(15008,-1,-1,@ownername) return (1) end -- VALIDATE ROLE NAME -- execute @ret = sp_validname @rolename if @ret <> 0 return (1) if (charindex('\', @rolename) > 0) begin raiserror(15006,-1,-1,@rolename) return (1) end if @rolename = 'sys' raiserror(15355,-1,-1) -- ERROR IF SYSUSERS NAME ALREADY EXISTS -- if user_id(@rolename) is not null OR @rolename IN ('system_function_schema','INFORMATION_SCHEMA') begin if exists (select name from sysusers where issqlrole = 1 and name = @rolename) raiserror(15363,-1,-1,@rolename) else raiserror(15023,-1,-1,@rolename) return (1) end -- OBTAIN NEW ROLE UID (RESERVE 16384-16399) -- if user_name(16400) IS NULL select @uid = 16400 else select @uid = min(uid)+1 from sysusers where uid >= 16400 and uid < (32767 - 1) -- stay in role range and user_name(uid+1) is null -- uid not in use if @uid is null begin raiserror(15065,-1,-1) return (1) end -- INSERT THE ROW INTO SYSUSERS -- insert into sysusers values (@uid, 0, @rolename, NULL, 0x00, getdate(), getdate(), @owner, NULL) -- FINALIZATION: PRINT/RETURN SUCCESS -- if @@error <> 0 return (1) raiserror(15424,-1,-1) return (0) -- sp_addrole go create procedure sp_addapprole @rolename sysname, -- name of new app role @password sysname -- password for app role as -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @ret int, -- return value of sp call @uid smallint -- CHECK FOR NULL PASSWORD if (@password is null) begin raiserror(15034,-1,-1) return (1) end -- CHECK PERMISSIONS -- if (not is_member('db_securityadmin') = 1) and (not is_member('db_owner') = 1) begin raiserror(15247,-1,-1) return (1) end -- DISALLOW USER TRANSACTION -- set implicit_transactions off if (@@trancount > 0) begin raiserror(15002,-1,-1,'sp_addapprole') return (1) end -- VALIDATE APPROLE NAME -- execute @ret = sp_validname @rolename if @ret <> 0 return (1) if (charindex('\', @rolename) > 0) begin raiserror(15006,-1,-1,@rolename) return (1) end if @rolename = 'sys' raiserror(15355,-1,-1) -- ERROR IF SYSUSERS NAME ALREADY EXISTS -- if user_id(@rolename) is not null OR @rolename IN ('system_function_schema','INFORMATION_SCHEMA') begin raiserror(15363,-1,-1,@rolename) return (1) end -- OBTAIN NEW APPROLE UID (RESERVE 1-4) -- if user_name(5) IS NULL select @uid = 5 else select @uid = min(uid)+1 from sysusers where uid >= 5 and uid < (16384 - 1) -- stay in users range and user_name(uid+1) is null -- uid not in use if @uid is null begin raiserror(15065,-1,-1) return (1) end -- INSERT THE ROW INTO SYSUSERS -- insert into sysusers values (@uid, 32, @rolename, NULL, 0x00, getdate(), getdate(), 1, convert(varbinary(256), pwdencrypt(@password))) -- FINALIZATION: PRINT/RETURN SUCCESS -- if @@error <> 0 return (1) raiserror(15425,-1,-1) return (0) -- sp_addapprole go CREATE PROCEDURE sp_change_users_login @Action varchar(10) -- REPORT / UPDATE_ONE / AUTO_FIX ,@UserNamePattern sysname = Null ,@LoginName sysname = Null AS -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES -- set nocount on declare @exec_stmt nvarchar(430) declare @ret int, @FixMode char(5), @cfixesupdate int, -- count of fixes by update @cfixesaddlogin int, -- count of fixes by sp_addlogin @dbname sysname, @loginsid varbinary(85), @110name sysname -- SET INITIAL VALUES -- select @dbname = db_name(), @cfixesupdate = 0, @cfixesaddlogin = 0 -- ERROR IF IN USER TRANSACTION -- if @@trancount > 0 begin raiserror(15289,-1,-1) return (1) end -- INVALIDATE USE OF SPECIAL LOGIN/USER NAMES -- if suser_sid(@LoginName) = 0x1 -- 'sa' begin raiserror(15287,-1,-1,@LoginName) return (1) end if user_id(@UserNamePattern) in (1,0,3,4) --dbo, public, INFORMATION_SCHEMA, system_function_schema begin raiserror(15287,-1,-1,@UserNamePattern) return (1) end -- HANDLE REPORT -- if upper(@Action) = 'REPORT' begin -- VALIDATE PARAMS -- if @UserNamePattern IS NOT Null or @LoginName IS NOT Null begin raiserror(15290,-1,-1,@Action,@UserNamePattern,@LoginName) return (1) end -- GENERATE REPORT -- select UserName = name, UserSID = sid from sysusers where issqluser = 1 and (sid is not null and sid <> 0x0) and suser_sname(sid) is null order by name return (0) end -- HANDLE UPDATE_ONE -- if upper(@Action) = 'UPDATE_ONE' begin -- CHECK PERMISSIONS -- if not is_member('db_owner') = 1 begin raiserror(15247,-1,-1) return (1) end -- ERROR IF PARAMS NULL -- if @UserNamePattern IS Null or @LoginName IS Null begin raiserror(15290,-1,-1,@Action,@UserNamePattern,@LoginName) return (1) end -- VALIDATE PARAMS -- -- Can ONLY remap SQL Users to SQL Logins! Should be no need -- for re-mapping NT logins, and if you try, you'll mess up -- the user status bits! if not exists (select name from sysusers where name = @UserNamePattern -- match user name and issqluser = 1) -- must be sql user begin raiserror(15291,-1,-1,'User',@UserNamePattern) return (1) end select @loginsid = sid from master.dbo.syslogins where loginname = @LoginName -- match login name and isntname = 0 -- cannot use nt logins if @loginsid is null begin raiserror(15291,-1,-1,'Login',@LoginName) return (1) end -- ERROR IF SID ALREADY IN USE IN DATABASE -- if exists (select sid from sysusers where sid = @loginsid and name <> @UserNamePattern) begin raiserror(15063,-1,-1) return (1) end -- CHANGE THE USERS LOGIN (SID) -- update sysusers set sid = @loginsid, updatedate = getdate() where name = @UserNamePattern and issqluser = 1 and sid <> @loginsid -- FINALIZATION: REPORT (ONLY IF NOT SUCCESSFUL) AND EXIT -- if @@error <> 0 or @@rowcount <> 1 raiserror(15295,-1,-1, 0) return (0) end -- ERROR IF NOT AUTO_FIX -- if upper(@Action) <> 'AUTO_FIX' begin raiserror(15286,-1,-1,@Action) return (1) end -- HANDLE AUTO_FIX -- -- CHECK PERMISSIONS -- if not is_srvrolemember('sysadmin') = 1 begin raiserror(15247,-1,-1) return (1) end -- VALIDATE PARAMS -- if @UserNamePattern IS Null or @LoginName IS NOT Null begin raiserror(15290,-1,-1,@Action,@UserNamePattern,@LoginName) return (1) end -- LOOP THRU ORPHANED USERS -- select @exec_stmt = 'DECLARE ms_crs_110_Users cursor global for select name from sysusers where name = N' + quotename( @UserNamePattern , '''')+ ' and issqluser = 1 and suser_sname(sid) is null' EXECUTE (@exec_stmt) OPEN ms_crs_110_Users WHILE (110=110) begin FETCH next from ms_crs_110_Users into @110name if (@@fetch_status <> 0) begin DEALLOCATE ms_crs_110_Users BREAK end -- IS NAME ALREADY IN USE? -- -- if suser_sid(@110name) is null if not exists(select * from master.dbo.syslogins where loginname = @110name) begin -- ADD LOGIN -- execute @ret = sp_addlogin @110name, Null, @dbname if @ret <> 0 or suser_sid(@110name) is null begin raiserror(15497,16,1,@110name) deallocate ms_crs_110_Users return (1) end select @FixMode = '1AddL' raiserror(15293,-1,-1,@110name) end ELSE begin Select @FixMode = '2UpdU' Raiserror(15292,-1,-1,@110name) end -- REPORT ERROR & CONTINUE IF DUPLICATE SID IN DB -- select @loginsid = suser_sid(@110name) if user_sid(@loginsid) is not null begin raiserror(15331,-1,-1,@110name) CONTINUE end -- UPDATE SYSUSERS ROW -- update sysusers set sid = @loginsid, updatedate = getdate() where name = @110name if @@error <> 0 begin raiserror(15498,17,127) deallocate ms_crs_110_Users return (1) end if @FixMode = '1AddL' Select @cfixesaddlogin = @cfixesaddlogin + 1 else Select @cfixesupdate = @cfixesupdate + 1 end -- loop 110 -- REPORT AND RETURN SUCCESS -- raiserror(15295,-1,-1,@cfixesupdate) raiserror(15294,-1,-1,@cfixesaddlogin) return (0) -- sp_change_users_login go create proc sp_fulltext_table @tabname nvarchar(517), @action varchar(50), @ftcat sysname = NULL, -- create: catalog name @keyname sysname = NULL -- create: name of unique index as declare @schemamodified int -- FULLTEXT MUST BE ACTIVE IN DATABASE -- if DatabaseProperty(db_name(), 'IsFulltextEnabled') = 0 begin raiserror(15601,-1,-1) return 1 end -- VALIDATE PARAMS -- if @action is null OR @action not in ('create','drop','activate','deactivate', 'start_change_tracking', 'stop_change_tracking', 'start_background_updateindex', 'stop_background_updateindex', 'update_index', 'start_full', 'start_incremental', 'stop') OR (@action not in ('create') and (@ftcat is not null or @keyname is not null)) OR (@action in ('create') and (@ftcat is null or @keyname is null)) begin raiserror(15600,-1,-1,'sp_fulltext_table') return 1 end -- DISALLOW USER TRANSACTION -- set implicit_transactions off if @@trancount > 0 begin raiserror(15002,-1,-1,'sp_fulltext_table') return 1 end -- VALIDATE TABLE NAME -- -- (1) Must exist in current database declare @objid int select @objid = object_id(@tabname, 'local') if @objid is null begin declare @curdbname sysname select @curdbname = db_name() raiserror(15009,-1,-1 ,@tabname, @curdbname) return 1 end -- (2) Must be a user table (and not a temp table) if ObjectProperty(@objid, 'IsUserTable') = 0 OR substring(parsename(@tabname,1),1,1) = '#' begin raiserror(15218,-1,-1 ,@tabname) return 1 end -- CHECK PERMISSION ON TABLE -- if (is_member('db_owner') = 0) AND (is_member('db_ddladmin') = 0) AND (is_member(user_name(ObjectProperty(@objid, 'ownerid'))) = 0) begin raiserror(15247,-1,-1) return 1 end -- CHECK DATABASE MODE (must not be read-only) -- if DATABASEPROPERTY(db_name(), 'IsReadOnly') = 1 begin raiserror(15635, -1, -1, 'sp_fulltext_table') return 1 end -- BEGIN TRAN AND LOCK TABLE -- begin tran dbcc lockobjectschema(@tabname) if @@error <> 0 begin goto error_abort_exit end -- OBTAIN CATALOG NAME FROM SYSOBJECTS & CHECK ACTION -- declare @ftcatid smallint select @ftcatid = ObjectProperty(@objid, 'TableFulltextCatalogId') if @ftcatid <> 0 and @action = 'create' begin raiserror(15605,-1,-1,@tabname) goto error_abort_exit end if @ftcatid = 0 and @action <> 'create' begin raiserror(15606,-1,-1,@tabname) goto error_abort_exit end if @action = 'create' begin -- CHECK CATALOG NAME -- select @ftcatid = null select @ftcatid = ftcatid from sysfulltextcatalogs where name = @ftcat if @ftcatid is null begin raiserror(7641,-1,-1,@ftcat) goto error_abort_exit end -- CHECK INDEX NAME (UNIQUE, SINGLE-KEY, 450-byte MAX, NON-NULLABLE) AND SET BIT IF FOUND -- if IndexProperty(@objid, @keyname, 'IsUnique') = 1 and IndexProperty(@objid, @keyname, 'UserKeyCount') = 1 and IndexProperty(@objid, @keyname, 'IsHypothetical') = 0 and exists (select * from syscolumns where id = @objid and name = Index_col(@tabname, IndexProperty(@objid, @keyname, 'IndexId'), 1) and length <= 450 and isnullable = 0) begin update sysindexes set status = status | 33554432 where id = @objid and name = @keyname and indid > 0 and indid < 255 end else begin raiserror(15607,-1,-1,@keyname) goto error_abort_exit end -- ADD CATALOG NAME TO SYSOBJECTS -- update sysobjects set ftcatid = @ftcatid where id = @objid -- ADD TO CATALOG DBCC CALLFULLTEXT ( 5, @ftcatid, @objid ) -- FTAddURL( @ftcatid, db_id(), @objid ) if @@error <> 0 goto error_abort_exit end if @action = 'drop' begin -- DROP FROM CATALOG (NO ERROR IF ALREADY DROPPED) -- DBCC CALLFULLTEXT ( 6, @ftcatid, @objid ) -- FTDropURL( @ftcatid, db_id(), @objid ) if @@error <> 0 goto error_abort_exit -- DELETE SYSDEPENDS ENTRIES FOR IMAGE COLUMNS, IF ANY -- delete sysdepends where [id] = @objid and depid = @objid and deptype = 1 and number in ( select colid from syscolumns where [id] = @objid and type = 34 and (colstat & 16) = 16 ) -- REMOVE CATALOG NAME AND BITS FROM SYSTEM TABLES -- update syscolumns set colstat = colstat & ~80, language = 0 where [id] = @objid update sysindexes set status = status & ~33554432 where [id] = @objid update sysobjects set status = status & ~200, ftcatid = 0 where [id] = @objid -- DELETE NOTIFICATIONS FROM SYSFULLTEXTNOTIFY -- delete sysfulltextnotify where tableid = @objid end if @action = 'activate' begin -- MUST HAVE AT LEAST ONE COLUMN MARKED FOR FULLTEXT INDEXING -- if not exists (select * from syscolumns where id = @objid and (colstat & 16) = 16) begin raiserror(15609, -1,-1,@tabname) goto error_abort_exit end -- NO ERROR IF INDEXING ALREADY ACTIVATED -- if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 1 begin rollback tran return 0 end update sysobjects set status = status | 8 where id = @objid if (ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 1) begin -- STOP A FULL/INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid -- START A FULL CRAWL FOR THE TABLE DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 0 ) if @@error <> 0 goto error_abort_exit end end if @action = 'deactivate' begin -- NO ERROR IF INDEXING ALREADY DEACTIVATED -- if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0 begin rollback tran return 0 end -- IF TABLE IS NOT ENABLED FOR NOTIFICATIONS -- if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0 begin -- SET STATE TO INACTIVE, SCHEMA-MODIFIED update sysobjects set status = ((status & ~72) | 128) where id = @objid end else begin -- SET STATE TO INACTIVE update sysobjects set status = (status & ~8) where id = @objid end -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid -- STOP EXISTING CRAWL (IMPLICIT STOP WITH WARNING) DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit end if @action = 'start_change_tracking' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if (ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0) begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF TABLE IS ALREADY ENABLED FOR NOTIFICATIONS -- if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 1 begin raiserror(15631,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF DATABASE IS IN SINGLE USER MODE -- if DATABASEPROPERTY(db_name(), 'IsSingleUser') = 1 begin raiserror(15637, -1, -1, @tabname) goto error_abort_exit end -- CHECK TO SEE IF THERE ARE ANY COLUMNS WHICH ARE NOT IN ROW BLOBS -- if (select count(*) from syscolumns where (id = object_id(@tabname)) and ((xtype = 34) or (xtype = 35) or (xtype = 99)) and ((colstat & 16) != 0) and (length = 16)) > 0 begin raiserror(15639, -1, -1, @tabname) end -- STOP EXISTING CRAWL DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid select @schemamodified = ObjectProperty(@objid, 'TableIsFulltextSchemaModified') -- SET TABLE TO CT ON. SCHEMA MOD. OFF -- update sysobjects set status = ((status & ~128) | 64) where id = @objid -- COMMIT TRAN -- NESCESSARY TO TURN ON CT BEFORE CRAWL IS KICKED OFF -- commit tran if @@error <> 0 goto error_abort_exit if (@schemamodified = 1) begin -- START A FULL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 0 ) if @@error <> 0 begin -- NEED TO RUN A FULL POPULATION raiserror(15644, -1, -1,@tabname, 'start_full') return 1 end end else begin -- START AN INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 1 ) if @@error <> 0 begin -- NEED TO RUN AN INCREMENTAL POPULATION raiserror(15644, -1, -1, @tabname, 'start_incremental') return 1 end end return 0 end if @action = 'stop_change_tracking' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if (ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0) begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end if (ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0) begin rollback tran return 0 end if(ObjectProperty(@objid, 'TableFulltextPopulateStatus') != 0) begin raiserror(7640,-1,-1, @tabname) end -- DISABLE FULLTEXT AUTO PROPAGATION (NO ERROR IF ALREADY DISABLED) -- DBCC CALLFULLTEXT ( 9, @objid ) -- FTDisableNotify( db_id(), @objid ) if @@error <> 0 goto error_abort_exit -- TURN OFF ACTIVE BITS IN SYSOBJECTS -- update sysobjects set status = status & ~192 where id = @objid if ((select count(*) from sysfulltextnotify where tableid = @objid) != 0) begin raiserror(7638,-1,-1, @tabname) end -- DELETE NOTIFICATIONS FROM SYSFULLTEXTNOTIFY -- delete sysfulltextnotify where tableid = @objid end if @action = 'start_background_updateindex' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0 begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF TABLE IS NOT ENABLED FOR NOTIFICATIONS -- if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0 begin raiserror(15632,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF FULLTEXT SCHEMA OF THE TABLE HAS BEEN MODIFIED (SHOULD NEVER HAPPEN)-- if (ObjectProperty(@objid, 'TableIsFulltextSchemaModified') = 1) begin raiserror(15640,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF TABLE IS ALREADY ENABLED FOR AUTO PROPAGATION -- if ObjectProperty(@objid, 'TableFulltextBackgroundUpdateIndexOn') = 1 begin raiserror(15633,-1,-1, @tabname) goto error_abort_exit end -- ENABLE TABLE FOR FULLTEXT AUTO PROPAGATION -- DBCC CALLFULLTEXT ( 10, @ftcatid, @objid ) -- FTEnableAutoProp( @ftcatid, db_id(), @objid ) if @@error <> 0 goto error_abort_exit -- TURN ON FULLTEXT AUTOPROPAGATION BIT IN SYSOBJECTS -- update sysobjects set status = status | 128 where id = @objid end if @action = 'stop_background_updateindex' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if (ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0) begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end if (ObjectProperty(@objid, 'TableFullTextBackgroundUpdateIndexOn') = 0) begin rollback tran return 0 end -- DISABLE FULLTEXT AUTO PROPAGATION (NO ERROR IF ALREADY DISABLED) -- DBCC CALLFULLTEXT ( 9, @objid ) -- FTDisableNotify( db_id(), @objid ) if @@error <> 0 goto error_abort_exit -- TURN OFF ACTIVE BITS IN SYSOBJECTS -- update sysobjects set status = status & ~128 where id = @objid end if @action = 'update_index' begin -- ERROR IF TABLE IS NOT ENABLED FOR NOTIFICATIONS -- if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0 begin raiserror(15634,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF TABLE IS NOT ACTIVE ANY MORE -- if (ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0) begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF FULLTEXT SCHEMA OF THE TABLE HAS BEEN MODIFIED -- THIS SHOULD NEVER HAPPEN if (ObjectProperty(@objid, 'TableIsFulltextSchemaModified') = 1) begin raiserror(15640,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF DATABASE IS IN SIGNLE USER MODE -- if DATABASEPROPERTY(db_name(), 'IsSingleUser') = 1 begin raiserror(15637, -1, -1, @tabname) goto error_abort_exit end DBCC CALLFULLTEXT ( 11, @ftcatid, @objid ) -- FTStartPropagation( db_id(), @ftcatid, @objid ) if @@error <> 0 goto error_abort_exit end if @action = 'start_full' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0 begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF DATABASE IS IN SINGLE USER MODE -- if DATABASEPROPERTY(db_name(), 'IsSingleUser') = 1 begin raiserror(15637, -1, -1, @tabname) goto error_abort_exit end -- RAISE WARNING IF POPULATE STATUS OF THE TABLE IS NOT IDLE if (ObjectProperty(@objid, 'TableFulltextPopulateStatus') != 0) begin raiserror(7636,-1,-1, @tabname) goto error_abort_exit end -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid -- START A FULL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 0 ) if @@error <> 0 goto error_abort_exit if (ObjectProperty(@objid, 'TableIsFulltextSchemaModified') = 1) and (ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0) -- SET TABLE SCHEMA-UNMODIFIED update sysobjects set status = status & ~128 where id = @objid end if @action = 'start_incremental' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0 begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF DATABASE IS IN SINGLE USER MODE -- if DATABASEPROPERTY(db_name(), 'IsSingleUser') = 1 begin raiserror(15637, -1, -1, @tabname) goto error_abort_exit end -- RAISE WARNING IF POPULATE STATUS OF THE TABLE IS NOT IDLE if (ObjectProperty(@objid, 'TableFulltextPopulateStatus') != 0) begin raiserror(7636,-1,-1, @tabname) goto error_abort_exit end -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid -- START AN INCREMENTAL POPULATION FOR THIS TABLE -- if (ObjectProperty(@objid, 'TableIsFulltextSchemaModified') = 1) and (ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0) begin -- FULL CRAWL IF SCHEMA MODIFIED DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 0 ) if @@error <> 0 goto error_abort_exit -- SET TABLE SCHEMA-UNMODIFIED update sysobjects set status = status & ~128 where id = @objid end else begin -- INCREMENTAL CRAWL DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 1 ) if @@error <> 0 goto error_abort_exit end end if @action = 'stop' begin -- ERROR IF TABLE IS NOT ACTIVATED -- if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 0 begin raiserror(15630,-1,-1, @tabname) goto error_abort_exit end -- ERROR IF POPULATE STATUS OF THE TABLE IS CRAWLING AND CT ON if (ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 1) and ((ObjectProperty(@objid, 'TableFulltextPopulateStatus') = 1) or (ObjectProperty(@objid, 'TableFulltextPopulateStatus') = 2)) begin raiserror(15642,-1,-1, @tabname) goto error_abort_exit end -- STOP A FULL/INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit end -- COMMIT TRAN -- commit tran if @@error <> 0 goto error_abort_exit -- SUCCESS -- return 0 error_abort_exit: rollback tran return 1 -- sp_fulltext_table go create proc sp_fulltext_column @tabname nvarchar(517), -- table name @colname sysname, -- column name @action varchar(20), -- add | drop @language int = null, -- LCID of data in the column @type_colname sysname = null -- column name, valid if colname is img as -- FULLTEXT MUST BE ACTIVE IN DATABASE -- if DatabaseProperty(db_name(), 'IsFulltextEnabled') = 0 begin raiserror(15601,-1,-1) return 1 end -- VALIDATE PARAMS -- if @action is null or @action not in ('add','drop') begin raiserror(15600,-1,-1,'sp_fulltext_column') return 1 end -- DISALLOW USER TRANSACTION -- set implicit_transactions off if @@trancount > 0 begin raiserror(15002,-1,-1,'sp_fulltext_column') return 1 end -- VALIDATE TABLE NAME -- -- (1) Must exist in current database declare @objid int select @objid = object_id(@tabname, 'local') if @objid is null begin declare @curdbname sysname select @curdbname = db_name() raiserror(15009,-1,-1 ,@tabname, @curdbname) return 1 end -- (2) Must be a user table if ObjectProperty(@objid, 'IsUserTable') = 0 begin raiserror(15218,-1,-1 ,@tabname) return 1 end -- CHECK PERMISSION ON TABLE -- if (is_member('db_owner') = 0) AND (is_member('db_ddladmin') = 0) AND (is_member(user_name(ObjectProperty(@objid, 'ownerid'))) = 0) begin raiserror(15247,-1,-1) return 1 end -- CHECK DATABASE MODE (must not be read-only) -- if DATABASEPROPERTY(db_name(), 'IsReadOnly') = 1 begin raiserror(15635, -1, -1, 'sp_fulltext_column') return 1 end -- BEGIN TRAN AND LOCK TABLE -- begin tran dbcc lockobjectschema(@tabname) if @@error <> 0 begin goto error_abort_exit end -- CHECK FOR CATALOG IN SYSOBJECTS -- declare @ftcatid smallint select @ftcatid = ObjectProperty(@objid, 'TableFulltextCatalogId') if @ftcatid = 0 begin raiserror(15606,-1,-1,@tabname) goto error_abort_exit end -- VALIDATE COLUMN NAME (CANNOT BE COMPUTED) -- declare @typename sysname select @typename = type_name(ColumnProperty(@objid, @colname, 'SystemType')) if @typename is null OR ColumnProperty(@objid, @colname, 'IsComputed') = 1 begin raiserror(15104,-1,-1,@tabname,@colname) goto error_abort_exit end -- VALIDATE PARAMETERS if (@action <> 'add' or @typename <> N'image') and @type_colname is not null begin raiserror(15600, -1, -1, 'sp_fulltext_column') goto error_abort_exit end if @action = 'add' begin -- VALIDATE COLUMN TYPE -- if @typename not in (N'nchar',N'nvarchar',N'ntext',N'char',N'varchar',N'text', N'image') begin raiserror(15611,-1,-1,@colname,@tabname) goto error_abort_exit end -- LANGUAGE if @language is null begin -- USE THE SERVER DEFAULT WORD BREAKING LANGUAGE select @language = value from master.dbo.syscurconfigs where config = 1126 end else begin -- VALIDATE @LANGUAGE ARGUMENT if @language < 0 begin raiserror(15600,-1,-1,'sp_fulltext_column') goto error_abort_exit end end update syscolumns set language = @language where id = @objid and name = @colname -- IF TABLE HAS ZERO INDEXED COLUMNS (THIS IS THE FIRST COLUMN TO BE ADDED), MARK IT ACTIVE if not exists (select * from syscolumns where id = @objid and (colstat & 16) = 16) and (ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0) and (ObjectProperty(@objid, 'TableIsFulltextSchemaModified') = 0) begin update sysobjects set status = (status | 8) where id = @objid end -- SET THE BIT FOR THIS COLUMN -- update syscolumns set colstat = colstat | 16 where id = @objid and name = @colname -- STOP A FULL/INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 1 begin if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 1 begin -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid -- START A FULL CRAWL FOR THE TABLE DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 0 ) if @@error <> 0 goto error_abort_exit end end else begin -- SET STATE TO SCHEMA_MODIFIED update sysobjects set status = ((status & ~64) | 128) where id = @objid end if @typename = N'image' begin -- VALIDATE THAT THE TYPE COLUMN IS GIVEN AND THAT IT IS VALID if @type_colname is null begin raiserror(15600, -1, -1, 'sp_fulltext_column') goto error_abort_exit end declare @typecolname sysname select @typecolname = type_name(ColumnProperty(@objid, @type_colname, 'SystemType')) -- TYPE COLUMN HAS TO BE A CHARACTER COLUMN if @typecolname not in (N'nchar',N'nvarchar',N'char',N'varchar') begin raiserror(15600 , -1, -1, 'sp_fulltext_column') goto error_abort_exit end -- ADD ENTRY OF COLID IN SYSDEPENDS declare @colid smallint declare @type_colid smallint select @colid = colid from syscolumns where [id] = @objid and name = @colname select @type_colid = colid from syscolumns where [id] = @objid and name = @type_colname if not exists ( select [id] from sysdepends where [id] = @objid and depid = @objid and number = @colid ) begin insert into sysdepends ([id], depid, number, depnumber, status, deptype ) values( @objid, @objid, @colid, @type_colid, 0, 1) end -- SET BIT INDICATING TYPE COLUMN update syscolumns set colstat = colstat | 64 where id = @objid and name = @type_colname end end else begin -- CLEAR THE BIT & ZERO LCID FOR THIS COLUMN -- update syscolumns set colstat = colstat & ~16, language = 0 where id = @objid and name = @colname -- IF LAST COLUMN DROPPED if not exists (select * from syscolumns where id = @objid and (colstat & 16) = 16) begin -- STOP A FULL/INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit -- IF TABLE HAS NOT BEEN DEACTIVATED if ((ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 1) or (ObjectProperty(@objid, 'TableIsFulltextSchemaModified') = 0)) begin -- IF CHANGE-TRACKING IS OFF if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 0 begin -- SET TABLE TO SCHEMA UNMODIFIED, INACTIVE (TURN OFF ALL BITS) update sysobjects set status = (status & ~200) where id = @objid end else begin -- SET TABLE TO INACTIVE update sysobjects set status = (status & ~8) where id = @objid end end end else if ObjectProperty(@objid, 'TableFulltextChangeTrackingOn') = 1 begin -- STOP A FULL/INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit if ObjectProperty(@objid, 'TableHasActiveFulltextIndex') = 1 begin -- DELETE SYSFULLTEXTNOTIFY ENTRIES delete sysfulltextnotify where tableid = @objid -- START A FULL CRAWL FOR THE TABLE DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 0 ) if @@error <> 0 goto error_abort_exit end end else begin -- STOP A FULL/INCREMENTAL POPULATION FOR THIS TABLE -- DBCC CALLFULLTEXT ( 12, @ftcatid, @objid, 2 ) if @@error <> 0 goto error_abort_exit -- SET BITS IN SYSOBJECTS update sysobjects set status = ((status & ~64) | 128) where id = @objid end -- IF IMAGE COLUMN, UNBIND FROM THE TYPE COLUMN if @typename = N'image' begin declare @colid1 smallint declare @type_colid1 smallint select @colid1 = colid from syscolumns where [id] = @objid and name = @colname select @type_colid1 = depnumber from sysdepends where [id] = @objid and depid = @objid and number = @colid1 delete sysdepends where [id] = @objid and depid = @objid and number = @colid1 and depnumber = @type_colid1 and deptype = 1 -- CLEAR BIT RELATING THE IMAGE COLUMN AND TYPE COLUMN if not exists ( select depnumber from sysdepends where [id] = @objid and depnumber = @type_colid1 and deptype = 1 and number in (select colid from syscolumns where [id] = @objid and type = 34 and (colstat & 16) = 16) ) begin update syscolumns set colstat = colstat & ~64 where [id] = @objid and colid = @type_colid1 end end end -- COMMIT TRAN -- commit tran if @@error <> 0 goto error_abort_exit -- SUCCESS -- return 0 error_abort_exit: rollback tran return 1 -- sp_fulltext_column go create procedure sp_helptext @objname nvarchar(776) ,@columnname sysname = NULL as set nocount on declare @dbname sysname ,@BlankSpaceAdded int ,@BasePos int ,@CurrentPos int ,@TextLength int ,@LineId int ,@AddOnLen int ,@LFCR int --lengths of line feed carriage return ,@DefinedLength int /* NOTE: Length of @SyscomText is 4000 to replace the length of ** text column in syscomments. ** lengths on @Line, #CommentText Text column and ** value for @DefinedLength are all 255. These need to all have ** the same values. 255 was selected in order for the max length ** display using down level clients */ ,@SyscomText nvarchar(4000) ,@Line nvarchar(255) Select @DefinedLength = 255 SELECT @BlankSpaceAdded = 0 /*Keeps track of blank spaces at end of lines. Note Len function ignores trailing blank spaces*/ CREATE TABLE #CommentText (LineId int ,Text nvarchar(255) collate database_default) /* ** Make sure the @objname is local to the current database. */ select @dbname = parsename(@objname,3) if @dbname is not null and @dbname <> db_name() begin raiserror(15250,-1,-1) return (1) end /* ** See if @objname exists. */ if (object_id(@objname) is null) begin select @dbname = db_name() raiserror(15009,-1,-1,@objname,@dbname) return (1) end -- If second parameter was given. if ( @columnname is not null) begin -- Check if it is a table if (select count(*) from sysobjects where id = object_id(@objname) and xtype in ('S ','U ','TF'))=0 begin raiserror(15218,-1,-1,@objname) return(1) end -- check if it is a correct column name if ((select 'count'=count(*) from syscolumns where name = @columnname and id = object_id(@objname) and number = 0) =0) begin raiserror(15645,-1,-1,@columnname) return(1) end if ((select iscomputed from syscolumns where name = @columnname and id = object_id(@objname) and number = 0) = 0) begin raiserror(15646,-1,-1,@columnname) return(1) end DECLARE ms_crs_syscom CURSOR LOCAL FOR SELECT text FROM syscomments WHERE id = object_id(@objname) and encrypted = 0 and number = (select colid from syscolumns where name = @columnname and id = object_id(@objname) and number = 0) order by number,colid FOR READ ONLY end else begin /* ** Find out how many lines of text are coming back, ** and return if there are none. */ if (select count(*) from syscomments c, sysobjects o where o.xtype not in ('S', 'U') and o.id = c.id and o.id = object_id(@objname)) = 0 begin raiserror(15197,-1,-1,@objname) return (1) end if (select count(*) from syscomments where id = object_id(@objname) and encrypted = 0) = 0 begin raiserror(15471,-1,-1) return (0) end DECLARE ms_crs_syscom CURSOR LOCAL FOR SELECT text FROM syscomments WHERE id = OBJECT_ID(@objname) and encrypted = 0 ORDER BY number, colid FOR READ ONLY end /* ** Else get the text. */ SELECT @LFCR = 2 SELECT @LineId = 1 OPEN ms_crs_syscom FETCH NEXT FROM ms_crs_syscom into @SyscomText WHILE @@fetch_status >= 0 BEGIN SELECT @BasePos = 1 SELECT @CurrentPos = 1 SELECT @TextLength = LEN(@SyscomText) WHILE @CurrentPos != 0 BEGIN --Looking for end of line followed by carriage return SELECT @CurrentPos = CHARINDEX(char(13)+char(10), @SyscomText, @BasePos) --If carriage return found IF @CurrentPos != 0 BEGIN /*If new value for @Lines length will be > then the **set length then insert current contents of @line **and proceed. */ While (isnull(LEN(@Line),0) + @BlankSpaceAdded + @CurrentPos-@BasePos + @LFCR) > @DefinedLength BEGIN SELECT @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) + @BlankSpaceAdded) INSERT #CommentText VALUES ( @LineId, isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N'')) SELECT @Line = NULL, @LineId = @LineId + 1, @BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0 END SELECT @Line = isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @CurrentPos-@BasePos + @LFCR), N'') SELECT @BasePos = @CurrentPos+2 INSERT #CommentText VALUES( @LineId, @Line ) SELECT @LineId = @LineId + 1 SELECT @Line = NULL END ELSE --else carriage return not found BEGIN IF @BasePos <= @TextLength BEGIN /*If new value for @Lines length will be > then the **defined length */ While (isnull(LEN(@Line),0) + @BlankSpaceAdded + @TextLength-@BasePos+1 ) > @DefinedLength BEGIN SELECT @AddOnLen = @DefinedLength - (isnull(LEN(@Line),0) + @BlankSpaceAdded) INSERT #CommentText VALUES ( @LineId, isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @AddOnLen), N'')) SELECT @Line = NULL, @LineId = @LineId + 1, @BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0 END SELECT @Line = isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText, @BasePos, @TextLength-@BasePos+1 ), N'') if LEN(@Line) < @DefinedLength and charindex(' ', @SyscomText, @TextLength+1 ) > 0 BEGIN SELECT @Line = @Line + ' ', @BlankSpaceAdded = 1 END END END END FETCH NEXT FROM ms_crs_syscom into @SyscomText END IF @Line is NOT NULL INSERT #CommentText VALUES( @LineId, @Line ) select Text from #CommentText order by LineId CLOSE ms_crs_syscom DEALLOCATE ms_crs_syscom DROP TABLE #CommentText return (0) -- sp_helptext go grant execute on sp_droplogin to public grant execute on sp_addsrvrolemember to public grant execute on sp_dropsrvrolemember to public grant execute on sp_grantdbaccess to public grant execute on sp_addalias to public grant execute on sp_addrole to public grant execute on sp_addapprole to public grant execute on sp_change_users_login to public grant execute on sp_fulltext_table to public grant execute on sp_fulltext_column to public grant execute on sp_helptext to public go -------------------------------------------------------------------------------- -- ODBC/OLEDB Catalog Procs (INSTCAT.SQL) -------------------------------------------------------------------------------- if (exists (select * from sysobjects where name = 'sp_tableswc' and type = 'P ')) drop proc sp_tableswc go print 'creating sp_tableswc' go create procedure sp_tableswc( @table_name nvarchar(384) = null, @table_owner nvarchar(384) = null, @table_qualifier sysname = null, @table_type varchar(100) = null) as declare @databasename sysname declare @qualprocname nvarchar(141) /* 128 + '..sp_tables' */ create table #sptables ( TABLE_QUALIFIER sysname collate database_default null, TABLE_OWNER sysname collate database_default null, TABLE_NAME sysname collate database_default null, TABLE_TYPE varchar(32) collate database_default null, REMARKS varchar(254) collate database_default null) declare databases CURSOR FOR select name from master..sysdatabases where name like @table_qualifier and name <> 'model' and has_dbaccess(name)=1 for read only open databases fetch next from databases into @databasename while (@@FETCH_STATUS <> -1) begin if (charindex('%', @databasename) = 0) begin /* skip dbnames w/wildcard characters to prevent loop */ select @qualprocname = @databasename + '..sp_tables' insert into #sptables exec @qualprocname @table_name, @table_owner, @databasename, @table_type end fetch next from databases into @databasename end deallocate databases select * from #sptables order by 4, 1, 2, 3 go grant execute on sp_tableswc to public go -- Since we are updating the contents of instcat.sql and therefore the contents -- of the ODBC/OLEDB catalog procs, we need to update the SPROC version update spt_server_info set attribute_value = '8.00.375' where attribute_id = 500 go -------------------------------------------------------------------------------- -- End of SQLDMO System Procedures (SQLDMO.SQL) -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- END OF FILE: Turn off marking of system objects. -- DO NOT ADD ANYTHING AFTER THIS POINT -------------------------------------------------------------------------------- exec sp_MS_upd_sysobj_category 2 go exec sp_configure 'allow updates',0 go reconfigure with override go